home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / drdobbs / 1987 / 12 / naro / misc.c < prev    next >
Text File  |  1987-12-21  |  22KB  |  234 lines

  1. #include <stdio.h>                                                                           
  2. #include <string.h>                                                                          
  3. #include <malloc.h>                                                                          
  4. #include <dos.h>                                                                             
  5. #include <errno.h>                                                                           
  6.                                                                                              
  7. #include "loc.h"                                                                             
  8. #include "externs.h"                                                                         
  9.                                                                                              
  10. extern   int   errno ;                                                                       
  11.                                                                                              
  12. char  *get_mem(size)                                                                         
  13. unsigned long  size ;                                                                        
  14. {                                                                                            
  15.    union REGS  regs ;                                                                        
  16.    char  *p ;                                                                                
  17.                                                                                              
  18.    /*                                                                                        
  19.       This function is a substitute for allocation of huge arrays.  It                       
  20.       uses DOS system calls to directly allocate up to 64K for a memory                      
  21.       block.                                                                                 
  22.    */                                                                                        
  23.                                                                                              
  24.    regs.x.bx = (unsigned int) (size / 16 + 1) ;                                              
  25.    regs.h.ah = 0x48 ;                                                                        
  26.    FP_SEG(p) = intdos(®s, ®s) ;                                                        
  27.    if (regs.x.cflag)   {                                                                     
  28.       errno = ENOMEM ;                                                                       
  29.       p = NULL ;                                                                             
  30.    }                                                                                         
  31.    else                                                                                      
  32.       FP_OFF(p) = 0 ;                                                                        
  33.                                                                                              
  34.    return   p ;                                                                              
  35. }                                                                                            
  36.                                                                                              
  37.                                                                                              
  38. void  free_mem(p)                                                                            
  39. char  *p ;                                                                                   
  40. {                                                                                            
  41.    union REGS  regs ;                                                                        
  42.    struct   SREGS sregs ;                                                                    
  43.                                                                                              
  44.    /*                                                                                        
  45.       This function is the complement of get_mem() in that it releases                       
  46.       any memory previously acquired with get_mem().                                         
  47.    */                                                                                        
  48.                                                                                              
  49.    sregs.es = FP_SEG(p) ;                                                                    
  50.    regs.h.ah = 0x49 ;                                                                        
  51.    intdosx(®s, ®s, &sregs) ;                                                           
  52.                                                                                              
  53.    return ;                                                                                  
  54. }                                                                                            
  55.                                                                                              
  56.                                                                                              
  57. int assign_physical_segment(class, seg)                                                      
  58. char     *class ;                                                                            
  59. unsigned int   seg ;                                                                         
  60. {                                                                                            
  61.    int   error = ERROR ;                                                                     
  62.    SEG_DESCRIPTOR *p ;                                                                       
  63.                                                                                              
  64.    /*                                                                                        
  65.       This function assigns the specified class name the physical                            
  66.       segment number.  The first segment within a named class will                           
  67.       have an offset of zero.  All other segments have a segment                             
  68.       offset relative to the first segment in the class.                                     
  69.    */                                                                                        
  70.                                                                                              
  71.    p = seg_list ;                                                                            
  72.    while (p != NULL)   {                                                                     
  73.       if (strcmp(p->class, class) == 0)   {                                                  
  74.          p->pseg += seg ;                                                                    
  75.          p->inited = TRUE ;                                                                  
  76.          error = OK ;                                                                        
  77.       }                                                                                      
  78.       p = p->next ;                                                                          
  79.    }                                                                                         
  80.    return   error ;                                                                          
  81. }                                                                                            
  82.                                                                                              
  83.                                                                                              
  84. int   get_next_segment(pclass, cclass, seg)                                                  
  85. char  *pclass ;                                                                              
  86. char  *cclass ;                                                                              
  87. unsigned int   *seg ;                                                                        
  88. {                                                                                            
  89.    int   error = ERROR ;                                                                     
  90.    BOOLEAN  found = FALSE ;                                                                  
  91.    SEG_DESCRIPTOR *p, *q, *last ;                                                            
  92.                                                                                              
  93.    /*                                                                                        
  94.       This function returns the next physical segment address                                
  95.       available for use by CCLASS (current class) after PCLASS                               
  96.       (previous class).  A typical use is to force the concatenation                         
  97.       of independent classes.                                                                
  98.    */                                                                                        
  99.                                                                                              
  100.    /* Search the class list for the occurrence of the CCLASS */                              
  101.    p = q = seg_list ;                                                                        
  102.    while (q != NULL)   {                                                                     
  103.       if (strcmp(q->class, cclass) == 0)   {                                                 
  104.          found = TRUE ;                                                                      
  105.          break ;                                                                             
  106.       }                                                                                      
  107.       q = q->next ;                                                                          
  108.    }                                                                                         
  109.                                                                                              
  110.    if (found == FALSE)                                                                       
  111.       return   ERROR ;           /* Error if it can't be found */                            
  112.                                                                                              
  113.    /* Search for PCLASS and then to the end of PCLASS. */                                    
  114.    while (p != NULL)   {                                                                     
  115.       if (strcmp(p->class, pclass) == 0)   {                                                 
  116.          last = p ;                                                                          
  117.          while(strcmp(p->class, pclass) == 0)   {                                            
  118.             last = p ;                                                                       
  119.             p = p->next ;                                                                    
  120.          }                                                                                   
  121.                                                                                              
  122.          /* Return the next available segment and adjust the segment                         
  123.             value for an overflow if necessary. */                                           
  124.                                                                                              
  125.          *seg = last->pseg + last->len / 16 ;                                                
  126.          if (q->offset < (last->len + last->offset) % 16)                                    
  127.             *seg += 1 ;                                                                      
  128.                                                                                              
  129.          return   OK ;                                                                       
  130.       }                                                                                      
  131.       p = p->next ;                                                                          
  132.    }                                                                                         
  133.    return   ERROR ;                                                                          
  134. }                                                                                            
  135.                                                                                              
  136.                                                                                              
  137. int   dup_class(old_class, new_class)                                                        
  138. char  *old_class ;                                                                           
  139. char  *new_class ;                                                                           
  140. {                                                                                            
  141.    int   error = ERROR ;                                                                     
  142.    SEG_DESCRIPTOR *p, *q, *prev, *head ;                                                     
  143.                                                                                              
  144.    /*                                                                                        
  145.       Copies the contents of the OLD_CLASS entry to the newly created                        
  146.       NEW_CLASS entry.                                                                       
  147.    */                                                                                        
  148.                                                                                              
  149.    p = seg_list ;                                                                            
  150.    while (p != NULL)   {                                                                     
  151.       if (strcmp(p->class, old_class) == 0)   {                                              
  152.          prev = head = NULL ;                                                                
  153.          while (p != NULL)   {                                                               
  154.             if (strcmp(p->class, old_class) != 0)                                            
  155.                break ;                                                                       
  156.                                                                                              
  157.             /* Create the new segment descriptor */                                          
  158.             if ((q = (SEG_DESCRIPTOR *) malloc(sizeof (*q))) == NULL) {                      
  159.                perror(__FILE__) ;                                                            
  160.                exit(1) ;                                                                     
  161.             }                                                                                
  162.                                                                                              
  163.             if (prev == NULL)                                                                
  164.                head = q ;                                                                    
  165.             else                                                                             
  166.                prev->next = q ;                                                              
  167.                                                                                              
  168.             /* Copy the contents and add the new entry to the list */                        
  169.             *q = *p ;                                                                        
  170.             strcpy(q->class, new_class) ;                                                    
  171.             q->next = NULL ;                                                                 
  172.                                                                                              
  173.             prev = q ;                                                                       
  174.             if (p->next == NULL)                                                             
  175.                break ;                                                                       
  176.             else                                                                             
  177.                p = p->next ;                                                                 
  178.          }                                                                                   
  179.          while (p->next != NULL)                                                             
  180.             p = p->next ;                                                                    
  181.                                                                                              
  182.          p->next = head ;                                                                    
  183.          return   OK ;                                                                       
  184.       }                                                                                      
  185.       p = p->next ;                                                                          
  186.    }                                                                                         
  187.    return   ERROR ;                                                                          
  188. }                                                                                            
  189.                                                                                              
  190.                                                                                              
  191. int rom_class(rom_class)                                                                     
  192. char  *rom_class;                                                                            
  193. {                                                                                            
  194.    int   error = ERROR ;                                                                     
  195.    SEG_DESCRIPTOR *p ;                                                                       
  196.                                                                                              
  197.    /*                                                                                        
  198.       Sets the romable field for the specified class to TRUE permitting                      
  199.       the output of the segment in the absolute object file.                                 
  200.    */                                                                                        
  201.                                                                                              
  202.    p = seg_list ;                                                                            
  203.    while (p != NULL)   {                                                                     
  204.       if (strcmp(p->class, rom_class) == 0)   {                                              
  205.          p->romable = TRUE ;                                                                 
  206.          error = OK ;                                                                        
  207.       }                                                                                      
  208.       p = p->next ;                                                                          
  209.    }                                                                                         
  210.    return   error ;                                                                          
  211. }                                                                                            
  212.                                                                                              
  213.                                                                                              
  214. int   locate_virtual_segment(vseg, pseg)                                                     
  215. unsigned int vseg;                                                                           
  216. unsigned int *pseg;                                                                          
  217. {                                                                                            
  218.    SEG_DESCRIPTOR *p ;                                                                       
  219.                                                                                              
  220.    /*                                                                                        
  221.       Finds an initialized segment with the specified virtual segment                        
  222.       number and returns the corresponding physical segment number.                          
  223.    */                                                                                        
  224.                                                                                              
  225.    p = seg_list ;                                                                            
  226.    while (p != NULL)   {                                                                     
  227.       if (p->inited == TRUE && p->vseg == vseg && p->len != 0)   {                           
  228.          *pseg = p->pseg ;                                                                   
  229.          return   OK ;                                                                       
  230.       }                                                                                      
  231.       p = p->next ;                                                                          
  232.    }                                                                                         
  233.    return   ERROR ;                                                                          
  234. }